package com.ruoyi.web.controller.wnjk.app;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.ruoyi.system.pay.service.IPayService;
import com.ruoyi.system.wnjk.contents.Contents;
import com.ruoyi.system.wnjk.domain.po.PhysicalOrder;
import com.ruoyi.system.wnjk.producer.DirectProducer;
import com.ruoyi.system.wnjk.service.IWnjkConsultationOrderService;
import com.ruoyi.system.wnjk.service.IWnjkPhysicalExaminationOrderService;
import com.ruoyi.system.wnjk.service.InventoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/app")
public class NotifyController {

    @Autowired
    private IWnjkPhysicalExaminationOrderService physicalExaminationOrderService;

    @Autowired
    private IPayService payService;

    @Autowired
    private InventoryService inventoryService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private PlatformTransactionManager transactionManager;

    @Value("${alipay.public-key}")
    private String alipayPublicKey;

    @Autowired
    private DirectProducer directProducer;

    @Autowired
    private IWnjkConsultationOrderService wnjkConsultationOrderService;
    /**
     * 处理支付宝支付回调
     */
    @PostMapping("/notify")
    public String handleAlipayNotify(HttpServletRequest request) {
        System.out.println("支付宝回调");
        System.out.println(":回调:"+request);
        String result = null;
        boolean isAlipayCallback = payService.verifyPayCallback(request);
        if (!isAlipayCallback) {
            System.out.println("【支付回调】非支付宝合法回调，验证失败");
            return "failure";
        }

        Map<String, String> params = new HashMap<>();
        for (String name : request.getParameterMap().keySet()) {
            params.put(name, request.getParameter(name));
        }
        String type = params.get("out_trade_no").substring(0, 2);

        // 体检支付回调
        if (type.equals(Contents.Pay.TYPE_TJ_PHYSICAL)) {
            result = tjNotify(params);

        } else if (type.equals(Contents.Pay.TYPE_GH_REGISTRATION)) {
            // 挂号支付回调

        } else if (type.equals(Contents.Pay.TYPE_WZ_INTERROGATION)) {
            // 问诊支付回调
            result = handleAlipayCallback(request);
        } else if (type.equals(Contents.Pay.TYPE_GW_SHOP)) {
            // 购物支付回调

        }

        return result;
    }



    /**
     * 处理体检支付回调
     * @param params 支付宝回调参数
     * @return 处理结果，"success" 表示成功，"failure" 表示失败
     */
    private String tjNotify(Map<String, String> params) {
        TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
        return transactionTemplate.execute(new TransactionCallback<String>() {
            @Override
            public String doInTransaction(TransactionStatus status) {
                try {
                    String outTradeNo = params.get("out_trade_no").substring(2);
                    String tradeNo = params.get("trade_no");
                    String tradeStatus = params.get("trade_status");
                    String totalAmount = params.get("total_amount");

                    System.out.println("【支付回调】订单号: {" + outTradeNo + "}, 支付宝流水号: {" + tradeNo +
                            "}, 状态: {" + tradeStatus + "}, 金额: {" + totalAmount + "}");

                    // 验证支付宝签名
                    boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayPublicKey, "UTF-8", "RSA2");
                    if (!signVerified) {
                        System.out.println("【支付回调】签名验证失败");
                        return "failure";
                    }

                    // 查询订单
                    PhysicalOrder order = physicalExaminationOrderService.selectByOutTradeNo(outTradeNo);
                    if (order == null) {
                        System.out.println("【支付回调】订单号 {" + outTradeNo + "} 不存在");
                        return "failure";
                    }

                    // 验证订单金额与回调金额是否一致
                    BigDecimal orderAmount = order.getTotalAmount();
                    BigDecimal callbackAmount = new BigDecimal(totalAmount);
                    if (orderAmount.compareTo(callbackAmount) != 0) {
                        System.out.println("【支付回调】订单金额 {" + orderAmount + "} 与回调金额 {" + callbackAmount + "} 不一致");
                        return "failure";
                    }

                    // 获取库存锁定信息
                    String redisKey = "order:pending:" + outTradeNo;
                    String inventoryInfo = redisTemplate.opsForValue().get(redisKey);

                    // 处理支付成功（TRADE_SUCCESS 或 TRADE_FINISHED）
                    if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                        if ("待支付".equals(order.getStatus())) {
                            // 微调1：仅在 inventoryInfo 存在时确认扣减库存
                            // 原因：在继续支付场景下，库存可能已在首次支付时扣减，且 Redis 记录可能已过期（inventoryInfo 为 null）
                            // 如果 inventoryInfo 为 null，则跳过库存操作，避免重复扣减
                            if (inventoryInfo != null) {
                                String[] parts = inventoryInfo.split(":");
                                Long physicalId = Long.parseLong(parts[1]);
                                LocalDate date = LocalDate.parse(parts[2]);
                                String period = parts[3];
                                inventoryService.confirmStockDeduction(physicalId, date, period, outTradeNo);
                                redisTemplate.delete(redisKey); // 删除 Redis 记录
                                System.out.println("【支付回调】库存扣减确认，physicalId: {" + physicalId + "}, date: {" + date + "}, period: {" + period + "}");
                            } else {
                                System.out.println("【支付回调】订单 {" + outTradeNo + "} 库存记录已过期，跳过库存扣减");
                            }

                            // 更新订单状态为已支付
                            order.setStatus("已支付");
                            order.setTradeNo(tradeNo);
                            order.setUpdatedAt(new Date());
                            physicalExaminationOrderService.updateWnjkPhysicalExaminationOrder(order);
                            System.out.println("【支付回调】订单 {" + outTradeNo + "} 状态更新为已支付，流水号: " + tradeNo);
                        } else {
                            System.out.println("【支付回调】订单 {" + outTradeNo + "} 状态已更新，跳过处理");
                        }
                        return "success";
                    } else {
                        // 支付失败，恢复库存
                        // 微调2：仅在 inventoryInfo 存在时恢复库存
                        // 原因：继续支付场景下，Redis 记录可能已过期（inventoryInfo 为 null），无需重复恢复库存
                        if (inventoryInfo != null) {
                            String[] parts = inventoryInfo.split(":");
                            Long physicalId = Long.parseLong(parts[1]);
                            LocalDate date = LocalDate.parse(parts[2]);
                            String period = parts[3];
                            inventoryService.rollbackStock(physicalId, date, period, outTradeNo);
                            redisTemplate.delete(redisKey); // 删除 Redis 记录
                            System.out.println("【支付回调】库存已恢复，physicalId: {" + physicalId + "}, date: {" + date + "}, period: {" + period + "}");
                        } else {
                            System.out.println("【支付回调】订单 {" + outTradeNo + "} 库存记录已过期，跳过库存恢复");
                        }

                        // 更新订单状态为待支付
                        order.setStatus("待支付");
                        order.setUpdatedAt(new Date());
                        physicalExaminationOrderService.updateWnjkPhysicalExaminationOrder(order);
                        System.out.println("【支付回调】订单 {" + outTradeNo + "} 支付失败，状态更新为待支付");
                        return "failure";
                    }
                } catch (AlipayApiException e) {
                    System.err.println("【支付回调】支付宝 API 异常: " + e.getMessage());
                    status.setRollbackOnly();
                    return "failure";
                } catch (Exception e) {
                    System.err.println("【支付回调】处理异常: " + e.getMessage());
                    status.setRollbackOnly();
                    return "failure";
                }
            }
        });
    }

    //异步回调
    public String handleAlipayCallback(HttpServletRequest request) {
        boolean isAlipayCallback = payService.verifyPayCallback(request);
        //判断是否是支付宝回调
        if (isAlipayCallback) {
            //解析回调参数
            //订单号
            String orderId = request.getParameter("out_trade_no").substring(2);
            //流水号
            String tradeNo = request.getParameter("trade_no");
            //订单状态
            String tradeStatus = request.getParameter("trade_status");
            //支付金额
            String totalAmount = request.getParameter("total_amount");
            //输出日志
            System.out.println("【支付回调】订单号: {orderId,}, 支付宝流水号: {tradeNo}, 状态: {tradeStatus}");
            //判断订单状态
            if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                //更新订单状态
                wnjkConsultationOrderService.updateOrderStatus(orderId, tradeNo);
                return "success";
            }

        }
        return "failure";
    }

}
